#ifndef COMM_PROTOCOL_H
#define COMM_PROTOCOL_H

#include "stdint.h"
#include "string.h"
#ifdef __cplusplus
extern "C" {
#endif

typedef enum CommProtocolError {
    Error_None = 0,
    Error_UnknownFormat ,
    Error_Illegal_1 ,
    Error_Illegal_2 ,
    Error_CRCFailed ,
    Error_Code,
}CommProtocolError_t;

typedef struct CommProtocolPortable {
    int (*authenticate)(char *password);
    uint16_t (*randKey)();
    int (*sendResponse)(void *buffer,int size);
    int (*readData)(int index,void *buffer,int *size);
    int (*writeData)(int index,void *buffer,int size);
    int (*startOTA)(uint32_t file_size);
    int (*writeOTAData)(uint32_t address_offset,void *buffer,int size);
    int (*verifyOTA)(void);
} CommProtocolPortable_t;

typedef enum RequestType {
    RequestType_Auth = 0x01,
    RequestType_HeartBeat = 0x02,
    RequestType_Read = 0x03,
    RequestType_Write = 0x04,
    RequestType_OTA = 0x05,
    RequestType_Default = 0x06,
}RequestType_t;

typedef enum ResponseType {
    ResponseType_Auth = 0x01,
    ResponseType_Read = 0x03,
    ResponseType_Write = 0x04,
    ResponseType_OTA = 0x05,
    ResponseTyep_Default = 0x06,
}ResponseType_t;

typedef struct CommProtocolRequestHeader {
    uint16_t magic_number;
    uint16_t auth_code;
    uint16_t type;
    uint32_t length;
    uint16_t crc16;
}__attribute__((packed)) CommProtocolRequestHeader_t;

typedef struct CommProtocolResponseHeader {
    uint16_t magic_number;
    uint16_t type;
    uint16_t reserved;
    uint32_t length;
    uint16_t crc16;
}__attribute__((packed)) CommProtocolResponseHeader_t;

typedef struct CommProtocolReadRequestContent {
    int index;
}CommProtocolReadRequestContent_t;
typedef enum OTAType{
    comm_protocol_ota_type_start = 0x01,
    comm_protocol_ota_type_data = 0x02,
    comm_protocol_ota_type_stop,
}OTAType_t;

typedef enum OTAResponse_Type{
    ota_response_OK = 0x00,

    ota_start_filesize_error = 0x01,
    ota_start_packetsize_error = 0x02,
    ota_start_packetsnumber_error = 0x03,

    ota_write_nostart_error = 0x04,
    ota_write_packetindex_error = 0x05,
    ota_verify_error = 0x06,
}OTAResponse_Type_t;

void CommProtocol_init(CommProtocolPortable_t portable);
int  CommProtocol_parseRequest(void *buffer);
void CommProtocol_loop();



#ifdef __cplusplus
}
#endif

#endif

